package com.bawei.mall.product.service.impl;

import com.alibaba.fastjson.JSON;
import com.bawei.common.core.domain.R;
import com.bawei.common.core.exception.ServiceException;
import com.bawei.common.core.utils.DateUtils;
import com.bawei.common.core.utils.bean.BeanUtils;
import com.bawei.common.rabbit.domain.Message;
import com.bawei.common.rabbit.enums.QueueEnum;
import com.bawei.common.security.utils.SecurityUtils;
import com.bawei.mall.product.cache.ProductInfoCache;
import com.bawei.mall.product.domain.MallProductBrandInfo;
import com.bawei.mall.product.domain.MallProductInfo;
import com.bawei.mall.product.domain.MallProductSkuInfo;
import com.bawei.mall.product.domain.MallProductTypeInfo;
import com.bawei.mall.product.domain.model.*;
import com.bawei.mall.product.domain.reponse.ProductDetailsResponse;
import com.bawei.mall.product.domain.reponse.ProductInfoResponse;
import com.bawei.mall.product.domain.request.ProductInfoRequest;
import com.bawei.mall.product.mapper.MallProductInfoMapper;
import com.bawei.mall.product.service.*;
import com.bawei.system.domain.vo.EsDocInsertVo;
import com.bawei.system.remote.api.RemoteEsDocService;
import com.bawei.system.remote.api.RemoteEsIndexService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 商品信息Service业务层处理
 *
 * @author DongZeLiang
 * @date 2022-09-19
 */
@Service
@Slf4j
public class MallProductInfoServiceImpl implements IMallProductInfoService {

    @Autowired
    private MallProductInfoMapper mallProductInfoMapper;

    @Autowired
    private IMallProductSkuInfoService skuInfoService;

    @Autowired
    private IMallProductRuleInfoService ruleInfoService;

    public static final String INDEX_NAME="mall_product";

    @Autowired
    private ProductInfoCache productInfoCache;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RemoteEsDocService remoteEsDocService;

    @Autowired
    private RemoteEsIndexService remoteEsIndexService;

    @Autowired
    private IMallProductBrandInfoService productBrandInfoService;

    @Autowired
    private IMallProductTypeInfoService productTypeInfoService;

    @Autowired
    private IMallProductFootService productFootService;



    /**
     * 项目启动时，把商品数据初始化到ES中
     */
    @PostConstruct
    public void init() {
        loadingProductInfoToEs();
    }

    /**
     * 查询商品信息
     *
     * @param id 商品信息主键
     * @return 商品信息
     */
    @Override
    public ProductInfoResponse selectMallProductInfoById(Long id) {
        MallProductInfo mallProductInfo = mallProductInfoMapper.selectMallProductInfoById(id);
        ProductInfoResponse productInfoResponse = new ProductInfoResponse();
        BeanUtils.copyBeanProp(productInfoResponse, mallProductInfo);
        productInfoResponse.setSkuInfoList(
                skuInfoService.selectMallProductSkuInfoList(new MallProductSkuInfo() {{
                    setProductId(id);
                }})
        );
        return productInfoResponse;
    }

    @Override
    public ProductDetailsResponse selectProductDetailsById(Long productId) {
        if (productId == null || productId == 0) {
            throw new ServiceException("查询商品信息，依据不合法！");
        }
        ProductDetailsResponse productDetailsResponse = new ProductDetailsResponse();
        ProductModel productModel = mallProductInfoMapper.selectProductModelById(productId);
        if (productModel == null) {
            throw new ServiceException("查询商品信息，商品数据为空");
        }
        productDetailsResponse.setProduct(productModel);

        MallProductBrandInfo mallProductBrandInfo = productBrandInfoService.selectMallProductBrandInfoById(Long.valueOf(productModel.getBrandId()));
        if (mallProductBrandInfo == null) {
            throw new ServiceException("查询品牌信息，品牌数据为空");
        }
        productDetailsResponse.setBrand(mallProductBrandInfo);

        String jsonInput = "[\n" +
                "    {\n" +
                "        \"id\": 43,\n" +
                "        \"productAttributeCategoryId\": 3,\n" +
                "        \"name\": \"颜色\",\n" +
                "        \"selectType\": 0,\n" +
                "        \"inputType\": 0,\n" +
                "        \"inputList\": \"\",\n" +
                "        \"sort\": 100,\n" +
                "        \"filterType\": 0,\n" +
                "        \"searchType\": 0,\n" +
                "        \"relatedStatus\": 0,\n" +
                "        \"handAddStatus\": 1,\n" +
                "        \"type\": 0\n" +
                "    },\n" +
                "    {\n" +
                "        \"id\": 44,\n" +
                "        \"productAttributeCategoryId\": 3,\n" +
                "        \"name\": \"容量\",\n" +
                "        \"selectType\": 0,\n" +
                "        \"inputType\": 1,\n" +
                "        \"inputList\": \"16G,32G,64G,128G,256G,512G\",\n" +
                "        \"sort\": 0,\n" +
                "        \"filterType\": 0,\n" +
                "        \"searchType\": 0,\n" +
                "        \"relatedStatus\": 0,\n" +
                "        \"handAddStatus\": 0,\n" +
                "        \"type\": 0\n" +
                "    },\n" +
                "    {\n" +
                "        \"id\": 45,\n" +
                "        \"productAttributeCategoryId\": 3,\n" +
                "        \"name\": \"屏幕尺寸\",\n" +
                "        \"selectType\": 0,\n" +
                "        \"inputType\": 0,\n" +
                "        \"inputList\": \"\",\n" +
                "        \"sort\": 0,\n" +
                "        \"filterType\": 0,\n" +
                "        \"searchType\": 0,\n" +
                "        \"relatedStatus\": 0,\n" +
                "        \"handAddStatus\": 0,\n" +
                "        \"type\": 1\n" +
                "    },\n" +
                "    {\n" +
                "        \"id\": 46,\n" +
                "        \"productAttributeCategoryId\": 3,\n" +
                "        \"name\": \"网络\",\n" +
                "        \"selectType\": 0,\n" +
                "        \"inputType\": 1,\n" +
                "        \"inputList\": \"3G,4G,5G,WLAN\",\n" +
                "        \"sort\": 0,\n" +
                "        \"filterType\": 0,\n" +
                "        \"searchType\": 0,\n" +
                "        \"relatedStatus\": 0,\n" +
                "        \"handAddStatus\": 0,\n" +
                "        \"type\": 1\n" +
                "    },\n" +
                "    {\n" +
                "        \"id\": 47,\n" +
                "        \"productAttributeCategoryId\": 3,\n" +
                "        \"name\": \"系统\",\n" +
                "        \"selectType\": 0,\n" +
                "        \"inputType\": 1,\n" +
                "        \"inputList\": \"Android,IOS\",\n" +
                "        \"sort\": 0,\n" +
                "        \"filterType\": 0,\n" +
                "        \"searchType\": 0,\n" +
                "        \"relatedStatus\": 0,\n" +
                "        \"handAddStatus\": 0,\n" +
                "        \"type\": 1\n" +
                "    },\n" +
                "    {\n" +
                "        \"id\": 48,\n" +
                "        \"productAttributeCategoryId\": 3,\n" +
                "        \"name\": \"电池容量\",\n" +
                "        \"selectType\": 0,\n" +
                "        \"inputType\": 0,\n" +
                "        \"inputList\": \"\",\n" +
                "        \"sort\": 0,\n" +
                "        \"filterType\": 0,\n" +
                "        \"searchType\": 0,\n" +
                "        \"relatedStatus\": 0,\n" +
                "        \"handAddStatus\": 0,\n" +
                "        \"type\": 1\n" +
                "    }\n" +
                "]";
        ObjectMapper mapper = new ObjectMapper();
        try {
            List<ProductAttribute> productAttributeList = mapper.readValue(jsonInput, new TypeReference<List<ProductAttribute>>() {});
            productDetailsResponse.setProductAttributeList(productAttributeList);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        String json = "[\n" +
                "    {\n" +
                "        \"id\": 512,\n" +
                "        \"productId\": 26,\n" +
                "        \"productAttributeId\": 43,\n" +
                "        \"value\": \"金色,银色\"\n" +
                "    },\n" +
                "    {\n" +
                "        \"id\": 513,\n" +
                "        \"productId\": 26,\n" +
                "        \"productAttributeId\": 45,\n" +
                "        \"value\": \"5.0\"\n" +
                "    },\n" +
                "    {\n" +
                "        \"id\": 514,\n" +
                "        \"productId\": 26,\n" +
                "        \"productAttributeId\": 46,\n" +
                "        \"value\": \"4G\"\n" +
                "    },\n" +
                "    {\n" +
                "        \"id\": 515,\n" +
                "        \"productId\": 26,\n" +
                "        \"productAttributeId\": 47,\n" +
                "        \"value\": \"Android\"\n" +
                "    },\n" +
                "    {\n" +
                "        \"id\": 516,\n" +
                "        \"productId\": 26,\n" +
                "        \"productAttributeId\": 48,\n" +
                "        \"value\": \"3000\"\n" +
                "    }\n" +
                "]";

        try {
            List<ProductAttributeValue> productAttributeValues = mapper.readValue(json, new TypeReference<List<ProductAttributeValue>>(){});
            productDetailsResponse.setProductAttributeValueList(productAttributeValues);
        } catch (IOException e) {
            e.printStackTrace();
        }

        String skuStocks = "[\n" +
                "    {\n" +
                "        \"id\": 433,\n" +
                "        \"productId\": 26,\n" +
                "        \"skuCode\": \"201806070026001\",\n" +
                "        \"price\": 3788.00,\n" +
                "        \"stock\": 487,\n" +
                "        \"promotionPrice\": 3699.00,\n" +
                "        \"lockStock\": 0,\n" +
                "        \"spData\": \"8G,256G,天蓝色\"\n" +
                "    },\n" +
                "    {\n" +
                "        \"id\": 111,\n" +
                "        \"productId\": 26,\n" +
                "        \"skuCode\": \"201806070026002\",\n" +
                "        \"price\": 3999.00,\n" +
                "        \"stock\": 499,\n" +
                "        \"promotionPrice\": 3899.00,\n" +
                "        \"lockStock\": 0,\n" +
                "        \"spData\":\"8G,256G,黑色\"\n" +
                "    },\n" +
                "    {\n" +
                "        \"id\": 112,\n" +
                "        \"productId\": 26,\n" +
                "        \"skuCode\": \"201806070026003\",\n" +
                "        \"price\": 3788.00,\n" +
                "        \"stock\": 500,\n" +
                "        \"promotionPrice\": 3699.00,\n" +
                "        \"lockStock\": 0,\n" +
                "        \"spData\": \"8G,128G,黑色\"\n" +
                "    },\n" +
                "    {\n" +
                "        \"id\": 113,\n" +
                "        \"productId\": 26,\n" +
                "        \"skuCode\": \"201806070026004\",\n" +
                "        \"price\": 3999.00,\n" +
                "        \"stock\": 500,\n" +
                "        \"promotionPrice\": 3899.00,\n" +
                "        \"lockStock\": 0,\n" +
                "        \"spData\": \"8G,128G,天蓝色\"\n" +
                "    }\n" +
                "]";
        List<MallProductSkuInfo> mallProductSkuInfos = skuInfoService.selectMallProductSkuInfoList(productId);
        if (mallProductSkuInfos == null || mallProductSkuInfos.size() == 0) {
            throw new ServiceException("查询商品信息，SKU数据为空");
        }
        try {
            List<SkuStock> skuStocksList = mapper.readValue(skuStocks, new TypeReference<List<SkuStock>>(){});
            skuStocksList.forEach(skuInfo -> {
                mallProductSkuInfos.forEach(item->{
                     skuInfo.setId(Integer.valueOf(item.getId()));
                });
                String sku = skuInfo.getSpData();
                List<String> properties = splitProperties(sku);
                String SpData = convertToJson(properties);
                skuInfo.setSpData(SpData);
            });
            productDetailsResponse.setSkuStockList(skuStocksList);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

        /*
        productDetailsResponse.setSkuList(mallProductSkuInfos);
        MallProductRuleInfo ruleInfo = ruleInfoService.selectMallProductRuleInfoById(productModel.getRuleId());
        if (ruleInfo == null) {
            throw new ServiceException("查询商品规格信息，规格数据为空");
        }*/

        //添加浏览信息
        //productFootService.insertMallProductFoot(productModel.getId());
        return productDetailsResponse;
    }

    private static List<String> splitProperties(String input) {
        String[] parts = input.split(",");
        List<String> properties = new ArrayList<>();
        for (String part : parts) {
            properties.add(part.trim());
        }
        return properties;
    }
    private static String convertToJson(List<String> properties) {
        Map<String, StringBuilder> propertyMap = new HashMap<>();

        // Populate property map
        for (String property : properties) {
            if (property.contains("色")) {
                String[] keyValue = property.split("色");
                if (keyValue.length == 2) {
                    if (!propertyMap.containsKey("颜色")) {
                        propertyMap.put("颜色", new StringBuilder(keyValue[1]));
                    } else {
                        propertyMap.get("颜色").append("+").append(keyValue[1]);
                    }
                } else {
                    if (!propertyMap.containsKey("颜色")) {
                        propertyMap.put("颜色", new StringBuilder(property));
                    } else {
                        propertyMap.get("颜色").append("+").append(property);
                    }
                }
            } else {
                if (!propertyMap.containsKey("容量")) {
                    propertyMap.put("容量", new StringBuilder(property));
                } else {
                    propertyMap.get("容量").append("+").append(property);
                }
            }
        }

        // Convert property map to list of Property objects
        List<Property> jsonObjects = new ArrayList<>();
        propertyMap.forEach((key, value) -> {
            jsonObjects.add(new Property(key, value.toString()));
        });

        // Convert to JSON
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            return objectMapper.writeValueAsString(jsonObjects);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return "";
        }
    }

    // Simple Property class for storing key-value pairs
    static class Property {
        private String key;
        private String value;

        public Property(String key, String value) {
            this.key = key;
            this.value = value;
        }

        // Getters and Setters
        public String getKey() {
            return key;
        }

        public void setKey(String key) {
            this.key = key;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }

    /**
     * 查询商品信息列表
     *
     * @param mallProductInfo 商品信息
     * @return 商品信息
     */
    @Override
    public List<MallProductInfo> selectMallProductInfoList(MallProductInfo mallProductInfo) {
        return mallProductInfoMapper.selectMallProductInfoList(mallProductInfo);
    }

    /**
     * 新增商品信息
     *
     * @param productInfoRequest 商品信息
     * @return 结果
     */
    @Override
    @Transactional
    public int insertMallProductInfo(ProductInfoRequest productInfoRequest) {
        productInfoRequest.setCreateBy(String.valueOf(SecurityUtils.getUserId()));
        productInfoRequest.setCreateTime(DateUtils.getNowDate());
        int i = mallProductInfoMapper.insertMallProductInfo(productInfoRequest);
        if (i == 0) {
            return i;
        }

        skuInfoService.batchInsertProductSku(
                SkuModel.builderSkuModel(productInfoRequest.getId(), productInfoRequest.getSkuInfoList())
        );

        // 给搜索系统发送消息需要进行搜索更新
        try {
            rabbitTemplate.convertAndSend(QueueEnum.PRODUCT_ADD.queueName(),
                    Message.builderMsg(productInfoRequest.getId()));
        } catch (ServiceException serviceException) {
            throw new ServiceException("给搜索系统发送消息需要进行搜索更新失败！");
        }
        return i;
    }

    /**
     * 修改商品信息
     *
     * @param productInfoRequest 商品信息
     * @return 结果
     */
    @Override
    @Transactional
    public int updateMallProductInfo(ProductInfoRequest productInfoRequest) {
        productInfoRequest.setUpdateBy(String.valueOf(SecurityUtils.getUserId()));
        productInfoRequest.setUpdateTime(DateUtils.getNowDate());
        int i = mallProductInfoMapper.updateMallProductInfo(productInfoRequest);
        if (i == 0) {
            //将商品信息推送至MQ，异步更新ES
            try {
                rabbitTemplate.convertAndSend(QueueEnum.PRODUCT_ADD.queueName(),
                        Message.builderMsg(productInfoRequest.getId()));
            } catch (ServiceException serviceException) {
                throw new ServiceException("给搜索系统发送消息需要进行搜索更新失败！");
            }
            return i;
        }
        skuInfoService.deleteMallProductSkuInfoByProductId(productInfoRequest.getId());
        skuInfoService.batchInsertProductSku(
                SkuModel.builderSkuModel(productInfoRequest.getId(), productInfoRequest.getSkuInfoList())
        );
        return i;
    }

    /**
     * 批量删除商品信息
     *
     * @param ids 需要删除的商品信息主键
     * @return 结果
     */
    @Override
    public int deleteMallProductInfoByIds(Long[] ids) {
        skuInfoService.deleteMallProductSkuInfoByProductIds(ids);
        for (Long id : ids) {
            // 延迟执行
            productInfoCache.delayRemove(id);
        }
        return mallProductInfoMapper.deleteMallProductInfoByIds(ids);
    }

    /**
     * 删除商品信息信息
     *
     * @param id 商品信息主键
     * @return 结果
     */
    @Override
    public int deleteMallProductInfoById(Long id) {
        return mallProductInfoMapper.deleteMallProductInfoById(id);
    }

    /**
     * 商品总条数
     *
     * @param mallProductInfo 商品查询
     * @return
     */
    @Override
    public Long selectMallProductInfoCount(MallProductInfo mallProductInfo) {
        return mallProductInfoMapper.selectMallProductInfoCount(mallProductInfo);
    }

    /**
     * 商品上下架
     *
     * @param id
     * @param stats
     * @return
     */
    @Override
    @Transactional
    public void uploadInfo(Long id, String stats) {
        //校验id是否为空
        if(id==null){
            throw new RuntimeException("商品id不能为空");
        }
        mallProductInfoMapper.UpdateStats(id,stats);

        //查询商品skuinfos
        List<MallProductSkuInfo> mallProductSkuInfos = skuInfoService.selectMallProductSkuInfoList(id);
        if (CollectionUtils.isEmpty(mallProductSkuInfos)){
            throw new RuntimeException("商品id"+id+"下不存在sku信息");
        }

        if(stats.equals("2")){
            ArrayList<String> list = new ArrayList<>();
            for (MallProductSkuInfo mallProductSkuInfo : mallProductSkuInfos) {
                list.add(mallProductSkuInfo.getId());
            }
            remoteEsDocService.batchDeleteDocs(list,INDEX_NAME);
        }

        if(stats.equals("1")){
            //根据id查询商品信息
            MallProductInfo mallProductInfo = mallProductInfoMapper.selectMallProductInfoById(id);
            if (mallProductInfo == null) {
                throw new ServiceException("商品信息不存在");
            }
            //参数转换
            List<EsDocInsertVo> esDocInsertVo = transFormData(mallProductInfo,mallProductSkuInfos);
            remoteEsDocService.batchInsertDocs(esDocInsertVo);
        }

    }

    private List<EsDocInsertVo> transFormData(MallProductInfo mallProductInfo, List<MallProductSkuInfo> mallProductSkuInfos) {

        // 构建返回结果集
        List<EsDocInsertVo> esDocInsertVos = new ArrayList<>();

        MallProductBrandInfo mallProductBrandInfo = productBrandInfoService.selectMallProductBrandInfoById(Long.valueOf(mallProductInfo.getBrandId()));

        MallProductTypeInfo mallProductTypeInfo = productTypeInfoService.selectMallProductTypeInfoById(Long.valueOf(mallProductInfo.getType()));

        Map<String, Object> map = new HashMap<>();

        mallProductSkuInfos.stream().map(mallProductSkuInfo -> {
            EsDocInsertVo esDocInsertVo = new EsDocInsertVo();
            esDocInsertVo.setId(String.valueOf(mallProductSkuInfo.getId()));
            esDocInsertVo.setIndexName(INDEX_NAME);

            //BeanUtils.copyProperties(mallProductSkuInfo,esDocInsertVo);

            map.putAll(JSON.parseObject(JSON.toJSONString(mallProductSkuInfo), Map.class));
            map.putAll(JSON.parseObject(JSON.toJSONString(mallProductInfo), Map.class));
            map.putAll(JSON.parseObject(JSON.toJSONString(mallProductBrandInfo), Map.class));
            map.putAll(JSON.parseObject(JSON.toJSONString(mallProductTypeInfo), Map.class));

            esDocInsertVo.setData(map);
            esDocInsertVos.add(esDocInsertVo);

            return esDocInsertVos;

        }).collect(Collectors.toList());

        return esDocInsertVos;
    }

    @Override
    public void loadingProductInfoToEs() {
        //查询所有商品信息
        List<MallProductInfo> mallProductInfos = mallProductInfoMapper.selectMallProductInfoList(new MallProductInfo());
        if (mallProductInfos == null || mallProductInfos.size() == 0) {
            log.info("暂无需要同步的商品");
        }
        //调用ES查询索引是否存在
        R<Boolean> indexExit = remoteEsIndexService.indexExit("mall_product");
        if (!indexExit.getData()) {
            log.info("mall_product索引不存在,调用ES服务创建索引");
            //创建索引
            R<Boolean> indexCreate = remoteEsIndexService.indexCreate("mall_product");
            if (!indexCreate.getData()) {
                log.info("创建mall_product索引失败");
            }
            //批量同步商品信息到ES
            //构建参数
            List<EsDocInsertVo> esDocInsertVo = builderProductInfoToEs(mallProductInfos);
            //调用ES服务批量插入文档
            R<Boolean> batchInsert = remoteEsDocService.batchInsertDocs(esDocInsertVo);
            if (batchInsert.getCode()==200) {
                log.info("批量同步商品信息到ES成功");
            }

        }

    }

    @Override
    public void UpdateStats(Long id, String stats) {
        mallProductInfoMapper.UpdateStats(id,stats);
    }

    @Override
    public List<MallProductInfo> selectMallProductInfoAllList() {
        return mallProductInfoMapper.selectMallProductInfoAllList();
    }


    private List<EsDocInsertVo> builderProductInfoToEs(List<MallProductInfo> mallProductInfos) {
        List<EsDocInsertVo> esDocInsertVos = new ArrayList<>();
        mallProductInfos.stream().forEach(mallProductInfo -> {
            EsDocInsertVo esDocInsertVo = new EsDocInsertVo();
            esDocInsertVo.setId(String.valueOf(mallProductInfo.getId()));
            esDocInsertVo.setIndexName("mall_product");
            //对象转为Map
            Map<String, Object> data = JSON.parseObject(JSON.toJSONString(mallProductInfo), Map.class);
            esDocInsertVo.setData(data);
            esDocInsertVos.add(esDocInsertVo);
        });
        return esDocInsertVos;
    }
}
